/*-------------------------------------------------
*File name: NetworkFederate.cu
*--------------------------------------------------*/
//#include <config.h>
//#include "Messagebuffer.hh"

#include "RTI.hh"
#include <cstdlib>
#include <iostream>
#include <string>
#include <cassert>

#include "NetworkFederate.h"
#include "federation.h"
#include "imageprocessing.h"

//Classes
#define CLA_FOREST_NODE "ForestNode"
#define CLA_RIVER_NODE "RiverNode"
#define CLA_SENSOR_NODE "SensorNode"

//Attributes
#define ATT_POSITION_X "PositionX"
#define ATT_POSITION_Y "PositionY"
#define ATT_DENSITY "Density"
#define ATT_STATE "State"
#define ATT_IMAGEEXTENTX "ImageExtentX"
#define ATT_IMAGEEXTENTY "ImageExtentY"


using std::string;

int main()
{
	// create and run the federate
	NetworkFederate *networkFederate;

	networkFederate = new NetworkFederate(NETWORK_FEDERATE_NAME, FEDERATION_FILE_NAME);
	networkFederate->runFederate(FEDERATION_NAME);
	
	delete networkFederate;
	return 0;
}
//-------------------------------------------------
/**Constructor
**/
NetworkFederate::NetworkFederate(std::string federate_name, std::string fdd_name):
	rtiamb(),
	federateName(federate_name),
	fddName(fdd_name),
	handle(0),
	creator(false),
	nbTicks(0),
	regulating(false),
	constrained(false),
	notimestamp(false),
	localTime(0.0),
	TIME_STEP(1.0),
	joined(false)
{
}
//------------------------------------------------
/**Destructor
*/
NetworkFederate::~NetworkFederate()
	throw (RTI::FederateInternalError)
{
}
//--------------------------------------------------------------------------------------------
/** Main simualation
**/
#include <unistd.h>
#include <cuda.h>
#include <Xlib.h>
#include "view.h"
#include "dataFrontier.cu"
#include "dataSensorNet.cu"

#define WINDOW_TITLE "Cellular Automata with CUDA: Network Federate"

const int NUMBER_CYCLE = FEDERATION_CYCLE;

int NODE_NUMBER_SENSOR = sizeof(NetCells)/sizeof(CellArray);

Colormap colormap;
Display *dsp;
Window win;
GC gc;
int plotSize;
unsigned long white, black;

SensorNode *sensorNode;


void NetworkFederate::simulating()
{
	int NSize;

	sensorNode = (SensorNode*) malloc(NODE_NUMBER_SENSOR * sizeof(SensorNode));
	plotSize = 1;
	NSize = 256;
	dsp = XOpenDisplay(NULL);

	if (dsp == NULL)
	{ 
		printf("\n### Cannot connect to server.\n");
		return;
	}

	colormap = DefaultColormap(dsp, 0);

	int screenNumber = DefaultScreen(dsp);
	white = WhitePixel(dsp, screenNumber);
	black = BlackPixel(dsp, screenNumber);	

	win = XCreateSimpleWindow(dsp,
				DefaultRootWindow(dsp),
				50, 50,// origin
				NSize*plotSize*3, NSize*plotSize*3,// size
				0, black,//border
				COLOR_BACKGROUND//background
	);

	XStoreName(dsp, win, WINDOW_TITLE);
	XMapWindow(dsp, win);

	gc = XCreateGC(dsp, win, 0, NULL);	
	long eventMask = StructureNotifyMask;
	XSelectInput(dsp, win, eventMask);
	XEvent evt;

	//Displaying the frontier
	for (int i = 0; i < NODE_NUMBER_FRONTIER; i++)
	{
	    //Cells array comes from dataFrontier.cu file
	    showCell(Cells[i], dsp, colormap, win, gc, plotSize, -1);
	}

	for (int i = 0; i < NODE_NUMBER_SENSOR; i++)
	{
	    //Init sensor state
	    sensorNode[i].sensorState = SENSOR_NET_NORMAL;

	    //NetCells array comes from dataSensorNet.cu file
	    showCellNetwork(NetCells[i], dsp, colormap, win, gc, plotSize, SENSOR_NET_NORMAL, RANGE_SENSING, RANGE_COMMUNICATION);
	}

	printf("\n-- Click on the window to continue!\n");
	do
	{
		XNextEvent(dsp, &evt);
	}while(evt.type != MapNotify);
	
	RTI::ObjectHandle objectHandle = rtiamb.registerObjectInstance(SensorNodeClassID, NETWORK_FEDERATE_NAME);

	RTIfedTime nextStep;

	for (int i = 0; i < NUMBER_CYCLE; i++)
	{
	    //Reset sensor states
	    for (int j = 0; j < NODE_NUMBER_SENSOR; j++)
	    {
	    	showCellNetwork(NetCells[j], dsp, colormap, win, gc, plotSize, SENSOR_NET_NORMAL, RANGE_SENSING, RANGE_COMMUNICATION);		
	    }

	    nextStep = this->timeAdvance(1.0);

	    this->sendUpdate(sensorNode, NetCells, nextStep, objectHandle, NODE_NUMBER_SENSOR);

	    printf("=> Step %d finished!\n  Refreshing view ...\n", i + 1);
	}

	printf("\n-- Click on the window to continue!\n");

	eventMask = ButtonPressMask | ButtonReleaseMask;

	XSelectInput(dsp, win, eventMask);
	do{
		XNextEvent(dsp, &evt);
	}while(evt.type != ButtonRelease);

	//Releasing resources
	XDestroyWindow(dsp, win);
	XCloseDisplay(dsp);

	free(sensorNode);
}

void NetworkFederate::runFederate(std::string federation_name)
{
	int auto_start = 0;
	federationName = federation_name;
	//1. Creating the RTIambassador
	////finished in another way
	//2. Creating and joining to the federation
	this->createFederation(federationName);
	this->joinFederation(federationName);
	//3. Initialiazing the handles
	this->getHandles();
	
	this->pause();
	this->synchronize(auto_start);
	//7. Publishing and subscribing
	this->setTimeRegulation(true, true);
	this->publishAndSubscribe();
	//8. Registering an object to update
	
	//9. Doing the main simulation loop
	RTIfedTime nextStep;
	//RTI::ObjectHandle objectHandle = registerObject();
	this->simulating();
	//10. Deleting the object

	//11. Resigning from the federation
	rtiamb.resignFederationExecution(RTI::NO_ACTION);
	printf("\n-- Resigned from Federation!\n");
	//12. Destroying the federation
	try{
		rtiamb.destroyFederationExecution(FEDERATION_NAME);
		printf("\n-- Federation %s was destroyed!\n", FEDERATION_NAME);
	}catch(RTI::FederationExecutionDoesNotExist e)
	{
	     printf("\n### No need to destroy federation %s, it doesn't exist!\n", FEDERATION_NAME);
	}catch(RTI::FederatesCurrentlyJoined ex)
	{
	     printf("\n### Federate still joined, can't destroy federation %s!\n", FEDERATION_NAME);
	}

	//13. Cleaning up
}
//-----------------------------------------------
/** timeAdvance request
**/
RTIfedTime NetworkFederate::timeAdvance(RTIfedTime time_step)
{
	granted = false;

	try{
	    rtiamb.queryFederateTime(localTime);
	}catch(RTI::Exception& e)
	{
	      printf("\n### Exception requesting for federate local time");
	}

	try{
	   RTIfedTime time_at(localTime.getTime() + TIME_STEP.getTime());
	   //RTIfedTime time_at(localTime.getTime() + time_step);
	   printf("\n-- Time_at: %.2f - localtime: %.2f - timestep: %.2f\n", 
			time_at.getTime(), ((RTIfedTime&)localTime).getTime(), ((RTIfedTime&)TIME_STEP).getTime());
	   granted = false;
	   rtiamb.timeAdvanceRequest(time_at);

	}catch(RTI::Exception& e)
	{
		printf("\n### Exception with timeAdvancerequest!\n");
	}

	while(!granted)
	{
	     try{
	     	tick();
	     }catch(RTI::Exception& e)
	     {
		printf("\n### Exception ticking the RTI!\n");		
	     }
	}

	RTIfedTime next_step(localTime + TIME_STEP);
	return next_step;
}

//------------------------------------------------
/**Getting the federate handle
*/
RTI::FederateHandle NetworkFederate::getHandle() const
{
	return handle;
}
//------------------------------------------------
/** This method will get all the relevant handle information from the RTIambassador
***/
void NetworkFederate::getHandles()
{
	printf("\n-- Getting handles ...\n");
	//Getting classes
	SensorNodeClassID = rtiamb.getObjectClassHandle(CLA_SENSOR_NODE);
	ForestNodeClassID = rtiamb.getObjectClassHandle(CLA_FOREST_NODE);
	printf("\n-- NodeClassID = %d \n", (int) SensorNodeClassID);
	//Getting attributes
	SensorAttrXID = rtiamb.getAttributeHandle(ATT_POSITION_X, SensorNodeClassID);
	SensorAttrYID = rtiamb.getAttributeHandle(ATT_POSITION_Y, SensorNodeClassID);
	SensorAttrStateID = rtiamb.getAttributeHandle(ATT_STATE, SensorNodeClassID);
	SensorAttrImageExtentXID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTX, SensorNodeClassID);
	SensorAttrImageExtentYID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTY, SensorNodeClassID);

	ForestAttrXID = rtiamb.getAttributeHandle(ATT_POSITION_X, ForestNodeClassID);
	ForestAttrYID = rtiamb.getAttributeHandle(ATT_POSITION_Y, ForestNodeClassID);
	ForestAttrStateID = rtiamb.getAttributeHandle(ATT_STATE, ForestNodeClassID);
	ForestAttrImageExtentXID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTX, ForestNodeClassID);
	ForestAttrImageExtentYID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTY, ForestNodeClassID);
	
}
//------------------------------------------------
/**Blocking untils the user press enter
***/
void NetworkFederate::waitForUser()
{
	
}
//------------------------------------------------
/** Synchronizing with other federates
****/
void NetworkFederate::synchronize(int auto_start)
{	
	printf("\n-- Synchronizing ...\n");
	if (creator == true)
	{
	    if (auto_start == 0)
	    {	
		printf("\n>>>>>>>>>>>> Press ENTER to start execution <<<<<<<<<<<<<\n");
		getchar();
	    }
	    else
	    {
		while (auto_start >= 0)
		{
		      sleep(0);
		      printf("\r-- Autostart: %5d", auto_start);
		      fflush(stdout);
		      auto_start--;
		}
		printf("\n");
	    }
	    printf("\nCreator can resume execution...\n");
	    while(paused == false)
	    {
		try{
		    printf("\n-- Not paused!\n");
		    tick();
		}
		catch(RTI::Exception &e)
		{
		     printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     throw;
		}
	    }
	    printf("\n-- Execution is paused!\n");
	    
	    try {
		rtiamb.synchronizationPointAchieved("Init");
	    }
	    catch(RTI::Exception &e)
	    {
	     	printf("\n** Exception: Achieving a synchronization point by creator: %d\n", (int) &e);
	    }

	    while (paused == true)
	    {
		try{
		    tick();
		}
		catch(RTI::Exception &e)
		{
		     printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     throw;
		}
	    }
	}
	else//Not creator
	{
	    if (auto_start != 0)
	    {
		printf("\n-- Ignoring autostart because this federate is not creator\n");
	    }

	    printf("\n-- Synchronizing ...\n");
	    
	    if (paused == false)
	    {
		printf("\n-- Federate is not paused: too early!\n");
		while(paused == false)
		{
		     try{
			tick();
		     }
		     catch(RTI::Exception &e)
		     {
			  printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     	  throw;
		     }
		}
	    }
	    printf("\n-- Federate is paused.\n");
	    try {
		rtiamb.synchronizationPointAchieved("Init");
		printf("\n-- Pause is achieved.\n");
	    }
	    catch(RTI::Exception &e)
	    {
	     	printf("\n** Exception: Achieving a synchronization point by creator: %d\n", (int) &e);
	    }
	    printf("\n-- Federation is waiting until ending the pause ...\n");
	    while(paused == true)
	    {
		try{
		   tick();
		}
		catch(RTI::Exception &e)
		{ 
		       printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		       throw;
		}
	    }	
	    printf("\n-- End of pause.\n");
	}
	printf("\n-- Federation is synchronized.\n");
}
//------------------------------------------------
/**This method try to create a new federation in the case of no federation. Ortherwise, 
**/
void NetworkFederate::createFederation(std::string federation_name)
{
	try{
	   rtiamb.createFederationExecution(federation_name.c_str(), fddName.c_str());
	   printf("\n-- Federation execution named %s is created!\n", federation_name.c_str());
	   creator = true;
	}
	catch (RTI::FederationExecutionAlreadyExists &e){
	   printf("-- Exception: %s Reason is: %s. OK I can join it\n", e._name, e._reason);
	}
	catch (RTI::CouldNotOpenFED &e){
	   printf("** Federate %s : ERROR: %s Reason is: %s\n", federateName.c_str(), e._name, e._reason);
	   delete &rtiamb;
	   exit(0);
	}

}
//------------------------------------------------
/**It will join to the existing federation in case of the unjoined state.
*@federation_name: name of federation.
*
**/
void NetworkFederate::joinFederation(std::string federation_name)
{
	//Joining the federation
	
	if (joined == false)
	{
	   try{
		handle = rtiamb.joinFederationExecution(federateName.c_str(), federation_name.c_str(), this);
		joined = true;		
		printf("-- Federate %s was joined to federation named %s!\n", federateName.c_str(), federation_name.c_str());
	   }
	   catch (RTI::FederateAlreadyExecutionMember &e){
		printf("## Exception: Federate %s already exists!\n", federateName.c_str());
		throw;
	   }
	   catch (RTI::FederationExecutionDoesNotExist &e){
		printf("** Exception: Federate %s : FederationExecutionDoesNotExists! \n", federateName.c_str());
	   }
	   catch (RTI::Exception &e){
		printf("** Federate %s : Join Federation Execution failed!\n", federateName.c_str());
	   }
	}
	
}

//-------------------------------------------------------------------------
/**This method allow creator to put federation in pause!
***/

void NetworkFederate::pause()
{
	if (creator == true)
	{
	   printf("\n-- Pause requested ... \n");
	   try{
		rtiamb.registerFederationSynchronizationPoint("Init", "-- Waiting for all federates ... \n");
	   }
	   catch(RTI::Exception &e){
		printf("## Federate %s : Register Synchronization Point failed!\n", federateName.c_str());
	   }
	}
}

//---------------------------------------------------------------------
/** Ticking the RTI
**/
void NetworkFederate::tick()
{
	//usleep(0);
	printf("\r-- Tick...");
	rtiamb.tick();
	nbTicks++;
}

void NetworkFederate::publishAndSubscribe()
{
	//Get all calss and attributes handles
	//getHandles();
	int nbAttributes = 5;
	
	RTI::AttributeHandleSet *attributes = RTI::AttributeHandleSetFactory::create(nbAttributes);

	attributes->add(SensorAttrXID);
	attributes->add(SensorAttrYID);
	attributes->add(SensorAttrStateID);
	attributes->add(SensorAttrImageExtentXID);
	attributes->add(SensorAttrImageExtentYID);

	rtiamb.publishObjectClass(SensorNodeClassID, *attributes);

	attributes = RTI::AttributeHandleSetFactory::create(nbAttributes);
	attributes->add(ForestAttrXID);
	attributes->add(ForestAttrYID);
	attributes->add(ForestAttrStateID);
	attributes->add(ForestAttrImageExtentXID);
	attributes->add(ForestAttrImageExtentYID);

	rtiamb.subscribeObjectClassAttributes(ForestNodeClassID, *attributes, RTI::RTI_TRUE);

	printf("\n-- Publishing and subscribing done!\n");
}

void NetworkFederate::setTimeRegulation(bool start_constrained, bool start_regulating)
{
        printf("\n-- Time Regulation setup ...\n");

        if (start_constrained == true)
        {
           if (!constrained)
           {
                rtiamb.enableTimeConstrained();
                constrained = true;
                printf("\n-- Time Constrained enabled.\n");
           }
        }
        else
        {
            if (constrained)
            {
                rtiamb.disableTimeConstrained();
                constrained = false;
                printf("\n-- Time Constrained disabled.\n");
            }
        }
        if (start_regulating == true)
        {
           if (!regulating)
           {
                for (;;)
                {
                    rtiamb.queryFederateTime(localTime);
                    try {
                        rtiamb.enableTimeRegulation(localTime, TIME_STEP);
                        regulating = true;
                        break;
                    }catch(RTI::FederationTimeAlreadyPassed)
                    {
                        rtiamb.queryFederateTime(localTime);
                        RTIfedTime requestTime(((RTIfedTime&)localTime).getTime());
                        requestTime += TIME_STEP;

                        granted = false;
                        while(!granted)
                        {
                             try{
                                tick();
                             }catch(RTI::RTIinternalError)
                             {
                                printf("\n-- RTIinternalError Raised in tick.\n");
                                exit(-1);
                             }
                        }
                    }catch(RTI::RTIinternalError)
                    {
                        printf("\n-- RTIinternalError Raised in setTimeRegulating.\n");
                        exit(-1);
                    }
                }
           }
        }
        else
        {
            if (regulating)
            {
                rtiamb.disableTimeRegulation();
                regulating = false;
            }
        }
}


//void step();
void NetworkFederate::checkRegions()
{

}
//void synchronize(int);

void NetworkFederate::sendInteraction(double dx, double dy, const RTI::FedTime& InteractionTime, RTI::ObjectHandle id)
{
}

void NetworkFederate::sendInteraction(double, double, RTI::ObjectHandle)
{
	
}

void NetworkFederate::sendUpdate(SensorNode *sensorNode_h, CellArray *cells, const RTI::FedTime & UpdateTime, RTI::ObjectHandle id, int node_number)
{
	libhla::MessageBuffer buffer;
	RTI::AttributeHandleValuePairSet *attributeSet;
	char tag[] = NETWORK_FEDERATE_NAME;
	int nbAttribute = 5;
	attributeSet = RTI::AttributeSetFactory::create(node_number * nbAttribute);

	printf("\n-- Sending update class ID %d !\n", (int)id);

	int x, y, imgExtentWidth, imgExtentHeight;
	int state;

	for (int i = 0; i < node_number; i++)
	{
	    x = cells[i].position.x;
	    y = cells[i].position.y;
	    imgExtentWidth = cells[i].image.extent.width;
	    imgExtentHeight = cells[i].image.extent.height;
	    state = sensorNode_h[i].sensorState;

	    buffer.reset();
	    buffer.write_int32(x);
	    buffer.updateReservedBytes();
	    attributeSet->add(SensorAttrXID, static_cast<char*>(buffer(0)),buffer.size());

	    buffer.reset();
	    buffer.write_int32(y);
	    buffer.updateReservedBytes();
	    attributeSet->add(SensorAttrYID, static_cast<char*>(buffer(0)),buffer.size());

	    buffer.reset();
	    buffer.write_int32(imgExtentWidth);
	    buffer.updateReservedBytes();
	    attributeSet->add(SensorAttrImageExtentXID, static_cast<char*>(buffer(0)),buffer.size());

	    buffer.reset();
	    buffer.write_int32(imgExtentHeight);
	    buffer.updateReservedBytes();
	    attributeSet->add(SensorAttrImageExtentYID, static_cast<char*>(buffer(0)),buffer.size());

	    buffer.reset();
	    buffer.write_int32(state);
	    buffer.updateReservedBytes();
	    attributeSet->add(SensorAttrStateID, static_cast<char*>(buffer(0)),buffer.size());
	}

	try{
		if (notimestamp == true)
		{
		   rtiamb.updateAttributeValues(id, *attributeSet, tag);
		}else
		{
		   rtiamb.updateAttributeValues(id, *attributeSet, UpdateTime, tag);
		}
	}catch(RTI::Exception& e){
		printf("\n## Exception: %s (%s)\n",e._name, e._reason);
		delete attributeSet;
	}

	delete attributeSet;

}
// ----------------------------------------------------------------------------
/** Callback : discover object instance
 */
void
NetworkFederate::discoverObjectInstance(RTI::ObjectHandle theObject,
				RTI::ObjectClassHandle theObjectClass,
				const char */*theObjectName*/)
    throw (RTI::CouldNotDiscover, RTI::ObjectClassNotKnown, 
	   RTI::FederateInternalError)
{
	printf("\n-- discoverObjectInstance\n");
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////// Synchronization Point Callbacks ///////////////////////
///////////////////////////////////////////////////////////////////////////////
void NetworkFederate::synchronizationPointRegistrationSucceeded(const char* label)
	throw(RTI::FederateInternalError)
{
	printf("\n-- Successfully registered sync point: %s\n", label);
}

void NetworkFederate::synchronizationPointRegistrationFailed(const char* label)
	throw(RTI::FederateInternalError)
{
	printf("\n-- Failed to register sync point: %s\n", label);
}

void NetworkFederate::announceSynchronizationPoint(const char *label, const char */*tag*/)
    throw (RTI::FederateInternalError)
{
	if (strcmp(label, "Init") == 0)
	{
	    printf("\n-- Synchronization point announced: %s\n", label);
	    paused = true;
	}
}

void NetworkFederate::federationSynchronized(const char *label)
	throw(RTI::FederateInternalError)
{
	if (strcmp(label, "Init") == 0)
	{
	   printf("\n-- Federation Synchronized: %s\n", label);
	   paused = false;
	}
}


//-------------------------------------------------------------------------------
/** Callback: receive interaction
****/
void NetworkFederate::receiveInteraction(RTI::InteractionClassHandle theInteraction,
                            const RTI::ParameterHandleValuePairSet & theParameters,
			    const RTI::FedTime& /*theTime*/,
                            const char */*theTag*/,
			    RTI::EventRetractionHandle /*theHandle*/)
        		throw ( RTI::InteractionClassNotKnown, 
				RTI::InteractionParameterNotKnown,
				RTI::InvalidFederationTime,
               			RTI::FederateInternalError)
{
}
//------------------------------------------------------------------------------------
/** Callback: reflect attribute values with time
**/
void NetworkFederate::reflectAttributeValues(RTI::ObjectHandle theObject,
                                const RTI::AttributeHandleValuePairSet& theAttributes,
                                const RTI::FedTime& theTime, 
				const char *theTag,
                                RTI::EventRetractionHandle theHandle)
        		throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown,
               			RTI::InvalidFederationTime, RTI::FederateInternalError)
{
libhla::MessageBuffer buffer;

	printf("\n-- Reflect attribute values with time: object=%d, tag=%s, time=%.2f", 
			(int)theObject, theTag, convertTime(theTime));

	int nbAttributes = 0;
	nbAttributes = theAttributes.size();

	printf("\n-- Number of attributes: %d \n", nbAttributes);

	int x, y, state, width, height;
	float distance;

	RTI::ULong i, length;
	/// If there are fire appearing in the monitored control of destined sensors. 
	/// These sensors will be changed their color to red. 
	/// Others will be changed to default color (red).

	if (strcmp(theTag, FOREST_FEDERATE_NAME) == 0)
	{
	   for (i = 0; i < nbAttributes; i++)
	   {
	   	RTI::AttributeHandle attHandle = theAttributes.getHandle(i);
	    	length = theAttributes.getValueLength(i);
	    	buffer.resize(length);
	    	buffer.reset();
	    	theAttributes.getValue(i, static_cast<char*>(buffer(0)), length);
	    	buffer.assumeSizeFromReservedBytes();
	    
	    	if (attHandle == ForestAttrXID)
	    	{
		   x = buffer.read_int32();
	    	}else if (attHandle == ForestAttrYID)
	    	{	
		   y = buffer.read_int32();
	    	}else if (attHandle == ForestAttrImageExtentXID)
	    	{	
		   width = buffer.read_int32();
	    	}else if (attHandle == ForestAttrImageExtentYID)
	    	{	
		   height = buffer.read_int32();
	    	}else if (attHandle == ForestAttrStateID)
	    	{
		   state = buffer.read_int32();
		   ///Displaying received data on window
		   CellArray cell;
		   cell.position.x = x;
		   cell.position.y = y;	
		   cell.image.extent.width = width;
		   cell.image.extent.height = height;

		   if (state == FIRED)
		   {
			for (int j = 0; j < NODE_NUMBER_SENSOR; j++)
			{
			    distance = computeDistance(cell.position, NetCells[j].position);
			    if (distance <= RANGE_SENSING)
			    {
	    		       showCellNetwork(NetCells[j], dsp, colormap, win, gc, plotSize, SENSOR_NET_URGENT, RANGE_SENSING, RANGE_COMMUNICATION);
			       sensorNode[j].sensorState = SENSOR_NET_URGENT;
			    }
			}
		   }else if (state == ASH)
		   {
		       	//do nothing	
		   }		
	    	}else
	    	   printf("\n-- Handle unkown\n");
	   }
	}
}

void NetworkFederate::reflectAttributeValues(RTI::ObjectHandle theObject,
                                const RTI::AttributeHandleValuePairSet & theAttributes,
                                const char *)
       	 		throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown,
               			RTI::FederateInternalError)
{
	printf("\n--reflectAttributeValues\n");
}

void NetworkFederate::receiveInteraction(RTI::InteractionClassHandle,
                            const RTI::ParameterHandleValuePairSet &,
                            const char *)
        		throw (RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown,
               			RTI::FederateInternalError)
{
	printf("\n--ReceiveInteraction\n");
}
void NetworkFederate::removeObjectInstance(RTI::ObjectHandle theObject, const RTI::FedTime& theTime,
                              const char *theTag,
                              RTI::EventRetractionHandle theHandle)
        		throw (RTI::ObjectNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError)
{
	printf("\n--removeObjectInstance\n");
}

void NetworkFederate::removeObjectInstance(RTI::ObjectHandle, const char *)
        		throw (RTI::ObjectNotKnown, RTI::FederateInternalError)
{

}

RTI::ObjectHandle NetworkFederate::registerObject()
{
	return rtiamb.registerObjectInstance(SensorNodeClassID);
}
//-----------------------------------------------------------------------------------------
/** Callback time advanced granted
**/
void NetworkFederate::timeAdvanceGrant(const RTI::FedTime& theTime)
	throw (RTI::FederateInternalError, RTI::TimeAdvanceWasNotInProgress,
               			RTI::InvalidFederationTime)
{
	granted = true;
	localTime = theTime;
	printf("\n-- Time advanced, local time is now %.2f.\n", localTime.getTime());
}

double NetworkFederate::convertTime(const RTI::FedTime& theTime)
{
	RTIfedTime time = (RTIfedTime)theTime;
	return time.getTime();
}
